#include "link/include/factory.h"
int factory_init(pfactory_t p,int threadnum,int quecapacity)
{
    p->threadnum=threadnum;
    p->startflag=0;
    pthread_cond_init(&p->cond,NULL);
    que_init(&p->que,quecapacity);
    //为存放线程id的数组申请空间
    p->pthid=(pthread_t*)calloc(threadnum,sizeof(pthread_t));
    return 0;
}
void *threadfunc(void *p)
{
    char sig;//用于接收信号
    int ret;
    pfactory_t pfac=(pfactory_t)p;
    pque_t pque=&pfac->que;
    pnode_t ptask;
    char lbuf[2]={0};
    while(1)
    {
        pthread_mutex_lock(&pque->q_mutex);
        if(0==pque->qsize)
        {
            pthread_cond_wait(&pfac->cond,&pque->q_mutex);
        }
        if(que_get(pque,&ptask)==-1)continue;
        pthread_mutex_unlock(&pque->q_mutex);
        printf("get taskk\n");
        strcpy(ptask->homepath,pfac->homepath);
        recv(ptask->newfd,&sig,1,0);
        if('1'==sig){login(pfac->conn,ptask);}
        else if('2'==sig){enroll(pfac->conn,ptask);}
        while(1)
        {//循环接收用户的请求
            ret=get_command(pfac->conn,ptask);
            if(-1==ret)
            {//客户端断开连接
                wrlog(pfac->conn,-2,lbuf,ptask);
                close(ptask->newfd);
                free(ptask);
                printf("Disconnected\n");
                break;
            }
        }
    }
}
int factory_start(pfactory_t p)
{
    if(!p->startflag)
    {
        for(int i=0;i<p->threadnum;++i)
        {
            pthread_create(p->pthid+i,NULL,threadfunc,p);
        }
        p->startflag=1;
    }
    return 0;
}
int que_init(pque_t pq,int quecapacity)
{
    bzero(pq,sizeof(que_t));
    pq->qcapacity=quecapacity;
    pq->qsize=0;
    pthread_mutex_init(&pq->q_mutex,NULL);//初始化线程锁
    return 0;
}
int que_set(pque_t pq,pnode_t pnod)
{
    if(NULL==pq->qhead)
    {
        pq->qhead=pq->qtail=pnod;
    }else{
        pq->qtail->pnext=pnod;
        pq->qtail=pnod;
    }
    ++pq->qsize;
    return 0;
}
int que_get(pque_t pq,pnode_t *ptask)//二级指针
{
    //这个判断用于防止主线程发送条件满足信号将要唤醒一个挂起的线程时，刚好有一个线程完成任务，
    //回到线程函数当中判断请求队列是否有任务的情况。这种情况下，可能会有两个线程同时进入本函数进行判断
    if(pq->qsize!=0)
    {
        *ptask=pq->qhead;
        pq->qhead=pq->qhead->pnext;
        if(NULL==pq->qhead)
        {
            pq->qtail=NULL;
        }
        --pq->qsize;
    }else return -1;
    return 0;
}
